React Server Componentsをアーキテクチャとしてどう捉えるか
#設計 #宣言的UIの設計レシピ #アーキテクチャ
koushisa.iconの視点でReact Server Components(RSC)の将来性を考える
まともな運用を考えるとフレームワーク利用が必須なのでApp Routerを利用する想定で書いてる
8割ぐらいドリームとポエム
関連
マイクロフロントエンドとキャッシュを前提としたCQSアーキテクチャを考える
概要
RSCはGraphQLとServer-Driven UIの中間みたいなイメージ
RSCやAppRouterはGraphQLの正統進化で、resolverがJSXを返すようなもの
Resolver(GraphQL)を置き換えるのではなく、さらにReact向けに特化したものとして考える
ApolloやRelayでやってたfragment colocation(コロケーション)をよりシンプルに実現できる
RESTで困っていなければ無理して採用する必要はない
こういうクラサバの跨ぎ方はアンチパターンと言われがち
境界づけられたコンテキストを跨いで共通化するな
境界は冗長で効率が悪いケースもある
不要な境界づけられたコンテキストが取っ払えると余分なインタフェースや変換層を消せる
関心の分離はドメインとプレゼンテーションから考える(PDS)
コード量を減らす(Write less code)
どちらにも当てはまらない境界もある
例えばEdgeとかキャッシュ管理系の処理はフロントエンドに近い位置で書きたい
主体をユーザーとしてみた時、境界は本当に必要なのだろうか?
ドメインをデータのワークフローと捉えるのか、ユーザーが期待する振る舞いと捉えるか
Smart UI
本質的にフロントエンドのための処理はフロントエンドに寄せることで全体の凝集度やアジリティを高めることができる
従来のクラサバ分離による境界づけられたコンテキストの世界観をRSCはぶっ壊す
フロントエンドが実ユーザーのリッチな要求に答え続ける形で技術的に進化を重ねた結果、堅牢かつ効率的に境界をまたげるようになった
Compositionの思想でコンポーネントツリーとReact Hooksは時空を分割して問題領域を十分に狭くできる
統合により開発効率を高めつつも、筋の良い副作用の抽象化により機能の入力-処理-出力を十分に分離できる
バックエンドへの影響
フロントエンドはRSC上でフェッチする
フロントエンドでのバックエンドとユースケースのインピーダンスミスマッチ
ドメイン知識及びリソースの状態や更新手順のカプセル化をどうする?
ドメイン知識
フロントエンド側で概念スキーマを外部スキーマに変換する層や制約を考慮する
リソースの状態や更新手順
必ず集約(Aggregate)単位で更新したい
ドメイン知識やDBのテーブル構造が頭に入っていないと理解が難しい
認知負荷的に課題がありそう
後述
API実装にまつわる煩雑さはマシになるかもしれない
バックエンド側の概念スキーマを外部スキーマに変換する層は不要になる
ドメインの概念と関係(relation), 関連(relationship), 制約の表現に専念できる
Web APIのオープンな特性に関する悩みが減る
粒度やバージョニング
意図されない使われ方していたり、知らないところで再利用されることを防げるので影響度が狭めやすい
公開するAPIを減らせる、というのはHyrumの法則的にも嬉しい
そういう意味ではRPCでもいいかも
デザインやユースケースに実装都合に引きずられた仕様をフロントエンドの実装者へ遅らせる事ができる
#決断を遅らせる
分業について
「Web API」というプロトコルを取っ払える
チーム間は必ず公開APIでやりとりする
チームの単位と問題領域が変わる
分業やモジュール性の考え方を改める必要がある
#マイクロフロントエンド
が、なんらかの形でDBへの知識をカプセル化するレイヤは必要になるはず
後述
開発組織の分け方はどうあるべきか
バックエンド/フロントエンドのように技術的な境界で分離したコンポーネントチームの構成だと却って効率が悪い
バックエンドとフロントエンドを統合したフィーチャーチームであればコミュニケーションはしやすいはず
コンウェイの法則も乗り越えやすい
従来の開発サイクルの変化
自然とフロントエンドを中心に考えるようになるはず
Smart UI、 Fullstack Components
デザイン思考をフロントエンドを起点とする力学が発生する
従来の流れ (Web API)
1. ユーザーストーリーに対しバックエンドが先頭に立って3層スキーマと必要なAPIを用意する
2. フロントエンドが用意されたAPIを繋ぎこむ #JSON色付け係
3. フロントエンドはAPI定義されるまで動きづらく前提知識が欠けて指示待ちになりやすい
RSCの場合
1. ユーザーストーリーに対し3層スキーマ > 外部スキーマの合意を取る
2. クライアントとサーバをRSCで組み込む
よりユーザー中心設計に近づく
フロントエンドに識者がいること前提
学習ハードルの高さや課題感はGraphQLと似てるが開発サイクルそのものを変えられる
ある程度バックエンドの知識を持っているフロントエンドがスキーマ定義に入れるとクエリの柔軟性が生まれる
恣意的なフロントエンド/バックエンドという肩書きによる分業は効率が悪い
コミュニケーションパスが増えると政治が発生する
同じ価値単位であれば一気通貫で実装できると理想的
一気通貫で実装するために
要件とデータ構造を小さく切り出す
価値単位による境界づけられたコンテキストを設計する
フロントエンドと価値を中心に一気通貫で考えながら作る(Write code thinking)
エンドユーザーにとっての価値を最速でもたらすことを念頭に考えると理想的なのかもしれない
構成
Next.js, Remix, Turborepoなどを筆頭としたモジュラモノリスが候補にあがる
フレームワークとしては現状はApp Router(まだベータ版)ぐらいしか選択肢がない
Web APIを取っ払える、といいつつも専門性によるインタフェース分離はしたくなると思う
RSCでDBを直で読み書きするのが横行してカオス化するのは容易に想像できる
DBへの読み書きを吸収するレイヤとしてのtRPCはよいのでは
いわゆるt3Stackと言われてるやつ
中大規模開発でRSCを採用するにはチーム構成やモジュール構成をよく練らないと数々の落とし穴にハマると思われる
構成やワークフローは若干複雑になるので興味本位で手を出すと痛い目を見るはず
デバッグ, モック, ロギング
Storybookやmswとの兼ね合いはどうだろうか
エコシステムが追従してくるのに時間差が生まれそうな気はする
現時点でここはGraphQLに優位性があるのでは
課題
既存の固定観念をアンラーニングして適応していけるか
リーダーに体力がないとレビューで死ぬ
認知負荷対策とワークフロー
構成(デバッグ, ロギング, モニタリング)
メモ
移行の際は、REST→GraphQLと似た道筋を通る気はする
→クライアント向けGraphQL入門
Next js v14 で考える開発チームの事業的貢献 - とろろこんぶろぐ
#わかってないこと
@koushisa: https://t.co/XjcjiaNuTp
Shared Componentsがきたら本格的にプロダクション見据えて素振りしよ
SvelteKitやSolidStartも似てるっちゃ似てる
UIを構築する手段としてSignal思想に優位性があるケースを理解できていない
RSCとはまた世界が別か